﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Media.Media3D;

namespace WokseleNaDrzewie
{
    class Convex
    {
        //wektor normalny:
        //N = (A, B, C)

        //płaszczyzna:
        //A*x + B*y + C*z + D = 0

        //D obliczamy tak:
        //D = -A*x - B*y - C*z

        //gdzie za (x,y,z) podstawisz jakieś współrzędne wierzchołka leżącego na
        //płaszczyźnie

        //Dla brył wypukłych jest najprościej, bo wystarczy dla każdej ściany
        //rozwiązać nierówność:

        //A*px + B*py + C*pz + D < 0

        //Jeżeli jest ono spełnione dla każdej ściany to punkt o współrzędnych
        //(px,py,pz) znajduje się wewnątrz bryły. Pod warunkiem, że bryłe
        //opisaliśmy w ten sposób, że wektory normalne każdej ściany są skierowane
        //na zewnątrz bryły.

        public static bool isInside(Rect3D rect, List<Triangle> triangles)
        {
            Point3D location = rect.Location;
            double x = rect.SizeX;
            double y = rect.SizeY;
            double z = rect.SizeZ;
            Point3D[] points = new Point3D[8];

            foreach (Triangle t in triangles)
            {
                Vector3D normal = t.normal;
                double D = -normal.X * t.center.X - normal.Y * t.center.Y - normal.Z * t.center.Z;
                points[0] = new Point3D(location.X, location.Y, location.Z);
                points[1] = new Point3D(location.X + x, location.Y, location.Z);
                points[2] = new Point3D(location.X, location.Y + y, location.Z);
                points[3] = new Point3D(location.X, location.Y, location.Z + z);
                points[4] = new Point3D(location.X + x, location.Y + y, location.Z);
                points[5] = new Point3D(location.X + x, location.Y, location.Z + z);
                points[6] = new Point3D(location.X, location.Y + y, location.Z + z);
                points[7] = new Point3D(location.X + x, location.Y + y, location.Z + z);
                foreach(Point3D p in points)
                    if (normal.X * p.X + normal.Y * p.Y + normal.Z * p.Z + D >= 0)
                        return false;
            }
            return true;
        }
    }
}
